package horde

import (
	"event-chain/core"

	"github.com/samber/lo"
)

func (c *Chain[T, K]) registerWrapper(opt OptType, f any, getKey func(T) K, isOnce, isPre bool, fn func(OptMap[T, K]) int) int {
	registerIndex := core.InValid
	if lo.IsNil(f) {
		c.logger.Errorf("register %s is nil", logOptMap[opt])
		return registerIndex
	}
	if opt == AlterOpt && lo.IsNil(getKey) {
		c.logger.Errorf("getKey is nil")
		return registerIndex
	}
	useOptMap := c.getRegisterMap(isPre)
	res := fn(useOptMap)
	if !isOnce {
		registerIndex = res
	}
	return registerIndex
}

func runWrapper[D, T any, K comparable](handleMap map[K][]T, data []D, fn func(T) ([]D, bool)) []D {
	var (
		delKeyMap = make(map[K][]int)
		isOnce    bool
	)
	if handleMap == nil {
		return data
	}
	for key, opts := range handleMap {
		for i, opt := range opts {
			data, isOnce = fn(opt)
			if isOnce {
				if _, has := delKeyMap[key]; !has {
					delKeyMap[key] = make([]int, 0)
				}
				delKeyMap[key] = append(delKeyMap[key], i)
			}
		}
	}
	for k, ints := range delKeyMap {
		if len(handleMap[k]) == len(ints) {
			wipe(handleMap, k, core.DelAll)
			continue
		}
		for _, i := range ints {
			wipe(handleMap, k, i)
		}
	}
	return data
}
